from PyQt5.Qt import *
import os
import sys


class Window(QWidget):
  def __init__(self):
    self.imageheight = 300
    super(Window, self).__init__()
    self.resize(800, 600)

    #self.listwidget = QtWidgets.QListWidget(self)
    #self.listwidget.resize(400,300)
    #self.listwidget.setGeometry(QtCore.QRect(0, 0, 300, 200))
    #self.listwidget.addItem("test")

    # print(os.path.dirname(os.path.abspath(__file__)) + r'\init_file\img\3333.png')
    # 图片路径要配置对
    help_img_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + r'\init_file\img'
    # print(help_img_dir)
    # 获取帮助图片
    # self.files_it = iter([os.path.join(help_img_dir, file) for file in os.listdir(help_img_dir)])
    # for item in self.files_it:
    #     print(item)
    # 生成帮助文本
    self.files_content = [
        {'type': 'txt', 'content': '第1步： xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
        {'type': 'img', 'content': help_img_dir + r'\3333.png'},
        {'type': 'txt', 'content': '第2步： xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
        {'type': 'img', 'content': help_img_dir + r'\3333.png'},
        {'type': 'txt', 'content': '第3步： xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
        {'type': 'img', 'content': help_img_dir + r'\3333.png'},
        {'type': 'txt', 'content': '第4步： xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
        {'type': 'img', 'content': help_img_dir + r'\3333.png'},
        {'type': 'txt', 'content': '第5步： xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'},
        {'type': 'img', 'content': help_img_dir + r'\3333.png'},
    ]

    # self.centralwidget = QtWidgets.QWidget(MainWindow)
    # self.gongzuomoshi = QtWidgets.QGroupBox(self.centralwidget)
    self.listWidget = QListWidget(self)
    #self.listWidget.setFixedWidth(600)
    container_layout = QVBoxLayout()
    g = QGroupBox('')
    l = FlowLayout()
    g.setLayout(l)
    for file in iter(self.files_content):
        if file['type'] == 'img':
            pixmap = QPixmap(file['content'])
            if not pixmap.isNull():
                autoWidth = pixmap.width()*self.imageheight/pixmap.height()
                label = QLabel(pixmap=pixmap)
                label.setScaledContents(True)
                label.setFixedHeight(self.imageheight)
                label.setFixedWidth(autoWidth)
                l.addWidget(label)
        if file['type'] == 'txt':
            label = QLabel(text=file['content'])
            l.addWidget(label)

    container_layout.addWidget(g)
    container_layout.addStretch()
    self.listWidget.setLayout(container_layout)

    self.qscrollarea = QScrollArea(self)
    self.qscrollarea.setGeometry(QRect(50, 100, 700, 500))
    self.qscrollarea.setWidgetResizable(True)
    self.qscrollarea.setWidget(self.listWidget)
    self.setWindowTitle("Flow Layout Scroll")


class FlowLayout(QLayout):
  """流式布局,使用说明
  1.声明流式布局 layout = FlowLayout
  2.将元素放入流式布局中
  3.将QGroupBox应用流式布局
  4.如果期望水平流式,将QGroupBox放入到QHBoxLayout,如果期望垂直布局,将QGroupBox放入到QVBoxLayout
  """
  heightChanged = pyqtSignal(int)

  def __init__(self, parent=None, margin=0, spacing=-1):
    super().__init__(parent)
    if parent is not None:
      self.setContentsMargins(margin, margin, margin, margin)
    self.setSpacing(spacing)

    self._item_list = []

  def __del__(self):
    while self.count():
      self.takeAt(0)

  def addItem(self, item): # pylint: disable=invalid-name
    self._item_list.append(item)

  def addSpacing(self, size): # pylint: disable=invalid-name
    self.addItem(Qt.QSpacerItem(size, 0, QSizePolicy.Fixed, QSizePolicy.Minimum))

  def count(self):
    return len(self._item_list)

  def itemAt(self, index): # pylint: disable=invalid-name
    if 0 <= index < len(self._item_list):
      return self._item_list[index]
    return None

  def takeAt(self, index): # pylint: disable=invalid-name
    if 0 <= index < len(self._item_list):
      return self._item_list.pop(index)
    return None

  def expandingDirections(self): # pylint: disable=invalid-name,no-self-use
    return Qt.Orientations(Qt.Orientation(0))

  def hasHeightForWidth(self): # pylint: disable=invalid-name,no-self-use
    return True

  def heightForWidth(self, width): # pylint: disable=invalid-name
    height = self._do_layout(QRect(0, 0, width, 0), True)
    return height

  def setGeometry(self, rect): # pylint: disable=invalid-name
    super().setGeometry(rect)
    self._do_layout(rect, False)

  def sizeHint(self): # pylint: disable=invalid-name
    return self.minimumSize()

  def minimumSize(self): # pylint: disable=invalid-name
    size = QSize()

    for item in self._item_list:
      minsize = item.minimumSize()
      extent = item.geometry().bottomRight()
      size = size.expandedTo(QSize(minsize.width(), extent.y()))

    margin = self.contentsMargins().left()
    size += QSize(2 * margin, 2 * margin)
    return size

  def _do_layout(self, rect, test_only=False):
    m = self.contentsMargins()
    effective_rect = rect.adjusted(+m.left(), +m.top(), -m.right(), -m.bottom())
    x = effective_rect.x()
    y = effective_rect.y()
    line_height = 0

    for item in self._item_list:
      wid = item.widget()

      space_x = self.spacing()
      space_y = self.spacing()
      if wid is not None:
        space_x += wid.style().layoutSpacing(
          QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal)
        space_y += wid.style().layoutSpacing(
          QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical)

      next_x = x + item.sizeHint().width() + space_x
      if next_x - space_x > effective_rect.right() and line_height > 0:
        x = effective_rect.x()
        y = y + line_height + space_y
        next_x = x + item.sizeHint().width() + space_x
        line_height = 0

      if not test_only:
        item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))

      x = next_x
      line_height = max(line_height, item.sizeHint().height())

    new_height = y + line_height - rect.y()
    self.heightChanged.emit(new_height)
    return new_height

if __name__ == '__main__':
  app = QApplication(sys.argv)
  mainWin = Window()

  mainWin.show()
  sys.exit(app.exec_())